home *** CD-ROM | disk | FTP | other *** search
/ Eagles Nest BBS 8 / Eagles_Nest_Mac_Collection_Disc_8.TOAST / Developer Tools⁄Additions / MacScheme20 / Compatibility / readtable.sch < prev    next >
Encoding:
Text File  |  1988-12-23  |  6.4 KB  |  148 lines  |  [TEXT/EDIT]

  1. ; Examples of the use of MacScheme's simple-minded reader
  2. ; customization procedures, readtable-ref and readtable-set!.
  3. ;
  4. ; The examples show how to make one character act like another,
  5. ; how to define non-terminating and terminating read-character-
  6. ; macros, and how to make #'x read as (function x) to aid in
  7. ; translating existing Lisp code into Scheme.
  8. ;
  9. ; Warning:  To save space, MacScheme maintains a single global
  10. ; readtable.  The readtable-set! procedure operates directly
  11. ; on this global readtable.  If you make a mistake, you may
  12. ; find yourself with an unusable readtable.
  13. ;
  14. ; Another warning:  Changes to the readtable do not affect the
  15. ; MacScheme user interface, so the Pick and Pick&Eval menu items
  16. ; may not work with the syntax you define.  You may have to select
  17. ; an expression using the mouse and choose Eval from the Commands
  18. ; menu in order to evaluate expressions that use your new syntax.
  19.  
  20. ; The following will make the [ and ] characters behave much like
  21. ; ( and ).  The main difference is that "dotted" notation currently
  22. ; doesn't work if the ] character is the closing bracket.
  23.  
  24. (readtable-set! #\[ (readtable-ref #\( ))
  25. (readtable-set! #\] (readtable-ref #\) ))
  26.  
  27. ; The following will make the { and } characters behave like
  28. ; alphabetic characters.  
  29.  
  30. (readtable-set! #\{ (readtable-ref #\a))
  31. (readtable-set! #\} (readtable-ref #\a))
  32.  
  33. ; A final warning: The data structures used by readtable-ref
  34. ; are insufficiently abstract and are hard to use, so they may
  35. ; be changed in a future version of MacScheme.  If this happens,
  36. ; some of the code that appears below will have to be changed.
  37.  
  38. ; A procedure for defining non-terminating read-macro-characters.
  39. ; The char argument specifies the macro character, and the proc
  40. ; argument is a procedure of two arguments that will be called
  41. ; when the macro character is scanned.  The first argument to
  42. ; proc will be the macro character and the second argument will
  43. ; be the port being read.  The macro character will already have
  44. ; been consumed from the port.
  45.  
  46. (define define-macro-character
  47.   (let ((typical-readtable-entry (readtable-ref #\a)))
  48.     (lambda (char proc)
  49.       (let ((readtable-entry (readtable-ref char)))
  50.         (readtable-set! char
  51.                         (cons 0
  52.                               (cons proc
  53.                                     (cddr typical-readtable-entry))))))))
  54.  
  55. ; The following example defines ? to be a read-macro-character
  56. ; such that ?x reads as (? . x).  Artificial intelligence researchers
  57. ; seem to like this.
  58.  
  59. (define-macro-character #\?
  60.   (lambda (c p)
  61.     (cons '? (read p))))
  62.  
  63. ; Sometimes a terminating read-macro-character is called for.
  64.  
  65. (define define-terminating-macro-character
  66.   (lambda (char proc)
  67.     (define-macro-character char proc)
  68.     (readtable-set! char (cons 2 (cdr (readtable-ref char))))))
  69.  
  70. ; The following example mimics the vertical bar syntax used in many
  71. ; dialects of Lisp for the purpose of writing symbols whose print
  72. ; names contain special characters or characters in the non-standard
  73. ; case.  It works only for input, and only when the entire symbol is
  74. ; enclosed within vertical bars.
  75.  
  76. (define-terminating-macro-character #\|
  77.   (lambda (c p)
  78.     (do ((c (read-char p) (read-char p))
  79.          (chars '() (cons c chars)))
  80.         ((char=? c #\|)
  81.          (string->symbol (list->string (reverse chars)))))))
  82.  
  83. ; It isn't easy to define new # macro characters in MacScheme.
  84. ; The following example makes #'x read as (function x) by redefining
  85. ; the action of the # character.  This might be part of a Common
  86. ; Lisp compatibility package for MacScheme.  (A simple compatibility
  87. ; package can get away with defining function as a macro such
  88. ; that (function x) expands to x; in a more sophisticated package
  89. ; the function macro would translate Common Lisp into Scheme.)
  90.  
  91. (let ((original-readtable-entry-for-# (readtable-ref #\#))
  92.       (original-readtable-entry-for-' (readtable-ref #\')))
  93.   (let ((syntax-category (car original-readtable-entry-for-#))
  94.         (dispatcher (cadr original-readtable-entry-for-#))
  95.         (list-dispatcher (caddr original-readtable-entry-for-#))
  96.         (quote-list-dispatcher
  97.          (caddr original-readtable-entry-for-')))
  98.     (readtable-set! #\#
  99.                     (list syntax-category
  100.                           (lambda (c p)
  101.                             (let ((c2 (peek-char p)))
  102.                               (if (char=? c2 #\')
  103.                                   (begin (read-char p)
  104.                                          (list 'function (read p)))
  105.                                   (dispatcher c p))))
  106.                           (lambda (c p)
  107.                             (let ((c2 (peek-char p)))
  108.                               (if (char=? c2 #\')
  109.                                   (begin
  110.                                    (read-char p)
  111.                                    (let* ((c (read-char p))
  112.                                           (x ((caddr (readtable-ref c)) c p)))
  113.                                      (cons (list 'function (car x)) (cdr x))))
  114.                                   (list-dispatcher c p))))))))
  115.  
  116. ; This code changes the MacScheme readtable to support a
  117. ; #|...|# syntax for comments.
  118.  
  119. (let ((original-readtable-entry-for-# (readtable-ref #\#)))
  120.   (let ((syntax-category (car original-readtable-entry-for-#))
  121.         (dispatcher (cadr original-readtable-entry-for-#))
  122.         (list-dispatcher (caddr original-readtable-entry-for-#)))
  123.     (define (flush-comment c p)
  124.       (if (and (char=? c #\|)
  125.                (char=? (peek-char p) #\#))
  126.           (read-char p)
  127.           (flush-comment (read-char p) p)))
  128.     (readtable-set! #\#
  129.                     (list syntax-category
  130.                           (lambda (c p)
  131.                             (let ((c2 (peek-char p)))
  132.                               (if (char=? c2 #\|)
  133.                                   (begin
  134.                                    (read-char p)
  135.                                    (flush-comment (read-char p) p)
  136.                                    (read p))
  137.                                   (dispatcher c p))))
  138.                           (lambda (c p)
  139.                             (let ((c2 (peek-char p)))
  140.                               (if (char=? c2 #\|)
  141.                                   (begin
  142.                                    (read-char p)
  143.                                    (flush-comment (read-char p) p)
  144.                                    (let ((c (read-char p)))
  145.                                      ((caddr (readtable-ref c)) c p)))
  146.                                   (list-dispatcher c p))))))))
  147.  
  148.